package com.itany.corejava.code08_常用类.string;

import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.Arrays;

/**
 * @author 石小俊
 * @version 1.0
 * @date 2023年03月16日 10:25
 */
public class Test09_字符集 {
    public static void main(String[] args) throws UnsupportedEncodingException {
//        query();
//        encoded();
//        decoded();
        garbled();
    }

    /**
     * 查询字符集
     */
    public static void query() {
        // 当前系统所使用的字符集
        System.out.println("当前系统所使用的字符集为:" + System.getProperty("file.encoding"));
        // JVM默认使用的当前操作系统的字符集
        System.out.println("JVM默认使用的当前操作系统的字符集:" + Charset.defaultCharset());
    }

    /**
     * 编码
     */
    public static void encoded() throws UnsupportedEncodingException {
        String s = "你好";
        // 对于GBK,占2个字节
        byte[] bytes = s.getBytes("GBK");
        // [-60, -29, -70, -61]
        System.out.println(Arrays.toString(bytes));
        // 对于UTF-8,占3个字节
        byte[] bytes2 = s.getBytes("UTF-8");
        // [-28, -67, -96, -27, -91, -67]
        System.out.println(Arrays.toString(bytes2));
    }

    /**
     * 解码
     */
    public static void decoded() throws UnsupportedEncodingException {
        byte[] bytes = {-60, -29, -70, -61};
        // 使用GBK进行解码
        String s = new String(bytes, "GBK");
        System.out.println(s);
        // 使用UTF-8进行解码
        byte[] bytes2 = {-28, -67, -96, -27, -91, -67};
        String s2 = new String(bytes2, "UTF-8");
        System.out.println(s2);

        // 使用系统默认的字符集进行解码
        // 当没有传递字符集的参数时,默认使用系统默认字符集
        s2 = new String(bytes2);
        System.out.println(s2);
    }

    /**
     * 乱码:编码与解码所使用的字符集不一致会产生乱码
     */
    public static void garbled() throws UnsupportedEncodingException {
        String s = "你好";

        // 编码-->使用GBK进行编码
        byte[] bytes = s.getBytes("GBK");
        System.out.println(Arrays.toString(bytes));

        // 乱码示例
        // 解码-->使用UTF-8解码
        String s2 = new String(bytes, "UTF-8");
        // 此时的GBK数据不符合UTF-8的规则
        // 在解码时,将原字符串的长度改变了
        // 原来2个字符-->4个字节-->3个字符-->9个字节
        // 这种情况无法恢复
        // System.out.println(s2);
        // System.out.println(s2.length());
        // 解码-->使用ISO-8859-1解码
        s2 = new String(bytes, "ISO-8859-1");
        System.out.println(s2);

        // 解决乱码问题,需要将乱码的字符串重新编码与解码
        // 使用该方式需要确保,当前编码所使用的字符集要符合解码的字符集规则
        // 否则转换不回来
        // 1.重新编码
        // 使用UTF-8的时候没有恢复
        // byte[] bytes2 = s2.getBytes("UTF-8");
        // 使用ISO8859-1是成功恢复了
        byte[] bytes2 = s2.getBytes("ISO-8859-1");
        System.out.println(Arrays.toString(bytes2));
        // 2.重新解码
        String s3 = new String(bytes2, "GBK");
        System.out.println(s3);

        // 简写方式
        String s4 = new String(s2.getBytes("ISO-8859-1"), "GBK");
        System.out.println(s4);

    }

}
